package org.karelun.gef.dom;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.swt.graphics.RGB;
import org.karelun.gef.editors.ClassDiagramEditor;
import org.karelun.gef.helper.DOMConstant;
import org.karelun.gef.model.AssociationConnectionModel;
import org.karelun.gef.model.AttributeModel;
import org.karelun.gef.model.ClassModel;
import org.karelun.gef.model.CombinationConnectionModel;
import org.karelun.gef.model.DependencyConnectionModel;
import org.karelun.gef.model.DiagramModel;
import org.karelun.gef.model.GeueralizationConnectionModel;
import org.karelun.gef.model.ImageModel;
import org.karelun.gef.model.MethodModel;
import org.karelun.gef.model.Node;
import org.karelun.gef.model.PackageModel;
import org.karelun.gef.model.RealizeConnectionModel;
import org.karelun.gef.model.RelationModel;
import org.karelun.gef.utils.ColorUtils;
import org.karelun.gef.utils.DOMUtils;
import org.w3c.dom.Element;

public class ReadClassDiagram {
	private ClassDiagramEditor editor;
	private Map<String,Node> map=new HashMap<String,Node>();
	
	public ReadClassDiagram(ClassDiagramEditor editor){
		this.editor=editor;
	}
	
	public void readXML(Element rootEle){
		DiagramModel diagram = editor.getDiagram();
		Element[] children = DOMUtils.getChildElements(rootEle);
		for(Element ele:children){
			String type = ele.getNodeName();
			if(DOMConstant.TAG_class.equals(type)){
				ClassModel model=new ClassModel();
				loadTextAndId(ele,model);
				loadLocation(ele,model);
				loadSize(ele,model);
				loadForeColor(ele,model);
				loadBackgroundColor(ele,model);
				
				Element[] attrEles = DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_attribute);
				for(Element attrEle:attrEles){
					AttributeModel attrModel=new AttributeModel();
					loadTextAndId(attrEle, attrModel);
					model.addAttribute(attrModel);
				}
				Element[] methodEles = DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_method);
				for(Element methodEle:methodEles){
					MethodModel methodModel=new MethodModel();
					loadTextAndId(methodEle, methodModel);
					model.addMethod(methodModel);
				}
				diagram.addNode(model);
			}else if(DOMConstant.TAG_relation.equals(type)){
				RelationModel relationModel=new RelationModel();
				loadTextAndId(ele, relationModel);
				loadLocation(ele, relationModel);
				loadSize(ele, relationModel);
				loadForeColor(ele, relationModel);
				loadBackgroundColor(ele, relationModel);
				diagram.addNode(relationModel);
			}else if(DOMConstant.TAG_package.equals(type)){
				PackageModel packageModel = new PackageModel();
				loadTextAndId(ele, packageModel);
				loadLocation(ele, packageModel);
				loadSize(ele, packageModel);
				loadForeColor(ele, packageModel);
				loadBackgroundColor(ele, packageModel);
				diagram.addNode(packageModel);
			}else if(DOMConstant.TAG_image.equals(type)){
				ImageModel imageModel = new ImageModel();
				loadTextAndId(ele, imageModel);
				loadLocation(ele, imageModel);
				loadSize(ele, imageModel);
				diagram.addNode(imageModel);
			}else if(DOMConstant.TAG_connection.equals(type)){
				Element sourceEle=DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_source)[0];
				String sourceNodeId=sourceEle.getAttribute(DOMConstant.ATTR_sourceNode);
				if(map==null||map.isEmpty())
					return;
				Node sourceNode=map.get(sourceNodeId);
				Element targetEle=DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_target)[0];
				String targetNodeId=targetEle.getAttribute(DOMConstant.ATTR_targetNode);
				Node targetNode=map.get(targetNodeId);
				
				String conn=ele.getAttribute(DOMConstant.ATTR_type);
				if(DOMConstant.assoc_connection.equals(conn)){
					AssociationConnectionModel connModel=new AssociationConnectionModel();
					connModel.setSource(sourceNode);
					connModel.setTarget(targetNode);
					sourceNode.addsourceConnection(connModel);
					targetNode.addtargetConnection(connModel);
				}else if(DOMConstant.combin_connection.equals(conn)){
					CombinationConnectionModel connModel=new CombinationConnectionModel();
					connModel.setSource(sourceNode);
					connModel.setTarget(targetNode);
					sourceNode.addsourceConnection(connModel);
					targetNode.addtargetConnection(connModel);
				}else if(DOMConstant.depend_connection.equals(conn)){
					DependencyConnectionModel connModel=new DependencyConnectionModel();
					connModel.setSource(sourceNode);
					connModel.setTarget(targetNode);
					sourceNode.addsourceConnection(connModel);
					targetNode.addtargetConnection(connModel);
				}else if(DOMConstant.geuera_connection.equals(conn)){
					GeueralizationConnectionModel connModel=new GeueralizationConnectionModel();
					connModel.setSource(sourceNode);
					connModel.setTarget(targetNode);
					sourceNode.addsourceConnection(connModel);
					targetNode.addtargetConnection(connModel);
				}else if(DOMConstant.realize_connection.equals(conn)){
					RealizeConnectionModel connModel=new RealizeConnectionModel();
					connModel.setSource(sourceNode);
					connModel.setTarget(targetNode);
					sourceNode.addsourceConnection(connModel);
					targetNode.addtargetConnection(connModel);
				}
			}
		}
	}

	private void loadBackgroundColor(Element ele, Node model) {
		Element bgColorEle = DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_BG_COLOR)[0];
		if(bgColorEle==null)
			return;
		String bgRgb = bgColorEle.getAttribute(DOMConstant.ATTR_COLOR);
		RGB bgColor = ColorUtils.toRGB(bgRgb);
		model.setBgColor(bgColor);
	}

	private void loadForeColor(Element ele, Node model) {
		Element foreColorEle = DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_FORE_COLOR)[0];
		if(foreColorEle==null)
			return ;
		String foreRgb = foreColorEle.getAttribute(DOMConstant.ATTR_COLOR);
		RGB foreColor = ColorUtils.toRGB(foreRgb);
		model.setForeColor(foreColor);
	}

	private void loadSize(Element ele, Node model) {
		Element sizeEle = DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_size)[0];
		if(sizeEle==null)
			return;
		String height = sizeEle.getAttribute(DOMConstant.ATTR_height);
		String width = sizeEle.getAttribute(DOMConstant.ATTR_width);
		model.setSize(new Dimension(Integer.parseInt(width),Integer.parseInt(height)));
	}

	private void loadLocation(Element ele, Node model) {
		Element locEle = DOMUtils.getChildElementsByTag(ele, DOMConstant.TAG_loc)[0];
		if(locEle==null)
			return;
		String x = locEle.getAttribute(DOMConstant.ATTR_x);
		String y = locEle.getAttribute(DOMConstant.ATTR_y);
		model.setLocation(new Point(Integer.parseInt(x),Integer.parseInt(y)));
	}

	private void loadTextAndId(Element ele, Node model) {
		String text = ele.getAttribute(DOMConstant.ATTR_name);
		model.setText(text);
		String id=ele.getAttribute(DOMConstant.ATTR_id);
		model.setId(id);
		map.put(id, model);
	}
}
